package com.rambler.common.weather.service;

import com.rambler.api.common.vo.qweather.response.*;
import com.rambler.common.config.QWeatherJwtProvider;
import com.rambler.common.config.QWeatherUrlConfig;
import com.rambler.common.response.CommonResponse;
import com.rambler.api.common.vo.qweather.QWeatherLocation;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Slf4j
@Service
public class QWeatherService {

    @Value("${weather.qweather-api.config.api-host}")
    private String apiHost;

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private QWeatherJwtProvider qWeatherJwtProvider;

    @Resource
    private QWeatherUrlConfig qWeatherUrlConfig;

    /**
     * 获取实时天气数据
     *
     * @param city 城市名称
     * @return 当前天气响应封装
     */
    public CommonResponse<QWeatherNowResponse> getNowWeather(String city) {
        try {
            QWeatherLocation location = searchCity(city);
            if (location == null) {
                return CommonResponse.failure("获取城市ID失败");
            }

            String url = String.format(qWeatherUrlConfig.getNowWeather(), apiHost, location.getId());
            System.out.println(url);
            HttpEntity<Void> entity = new HttpEntity<>(getHeaders());
            HttpHeaders headers = entity.getHeaders();
            System.out.println(headers);
            ResponseEntity<QWeatherNowResponse> response = restTemplate.exchange(url, HttpMethod.GET, entity,
                    QWeatherNowResponse.class);

            if (!response.getStatusCode().is2xxSuccessful() || response.getBody() == null) {
                String msg = "接口调用失败，返回状态码不为200或者响应体为空";
                // 记录日志
                log.error(msg);
                throw new RuntimeException(msg);
            }
            // if (!"200".equals(response.getBody().getCode().getCode())) {
            // String msg = "接口调用成功，和风天气服务内部故障";
            // // 记录日志
            // log.error(msg);
            // throw new RuntimeException(msg);
            // }
            return CommonResponse.success(response.getBody());
        } catch (Exception e) {
            return CommonResponse.failure("获取天气数据失败：" + e.getMessage());
        }
    }

    /**
     * 获取未来天气预报（按天）
     *
     * @param city 城市名称
     * @param days 支持值：3, 7, 10, 15, 30
     * @return 天气预报响应封装
     */
    public CommonResponse<QWeatherDailyForecastResponse> getWeatherDailyForecast(String city, Integer days) {
        // days只支持3,7,10,15,30
        if (days != 3 && days != 7 && days != 10 && days != 15 && days != 30) {
            return CommonResponse.failure("days只支持3, 5, 7, 10, 15, 30");
        }
        try {
            QWeatherLocation location = searchCity(city);
            if (location == null) {
                return CommonResponse.failure("获取城市ID失败");
            }

            String url = String.format(qWeatherUrlConfig.getDailyForecast(), apiHost, days, location.getId());
            HttpEntity<Void> entity = new HttpEntity<>(getHeaders());
            ResponseEntity<QWeatherDailyForecastResponse> response = restTemplate.exchange(url, HttpMethod.GET, entity,
                    QWeatherDailyForecastResponse.class);
            return CommonResponse.success(response.getBody());
        } catch (Exception e) {
            return CommonResponse.failure("获取按天天气预测数据失败：" + e.getMessage());
        }
    }

    /**
     * 获取未来天气预报（按小时）
     *
     * @param city  城市名称
     * @param hours 支持值：24, 72, 168
     * @return 小时级天气预报响应封装
     */
    public CommonResponse<QWeatherHourlyForecastResponse> getWeatherHourlyForecast(String city, Integer hours) {
        // days只支持3,7,10,15,30
        if (hours != 24 && hours != 72 && hours != 168) {
            return CommonResponse.failure("hours只支持24, 72, 168");
        }
        try {
            QWeatherLocation location = searchCity(city);
            if (location == null) {
                return CommonResponse.failure("获取城市ID失败");
            }

            String url = String.format(qWeatherUrlConfig.getHourlyForecast(), apiHost, hours, location.getId());
            HttpEntity<Void> entity = new HttpEntity<>(getHeaders());
            ResponseEntity<QWeatherHourlyForecastResponse> response = restTemplate.exchange(url, HttpMethod.GET, entity,
                    QWeatherHourlyForecastResponse.class);
            return CommonResponse.success(response.getBody());
        } catch (Exception e) {
            return CommonResponse.failure("获取按小时天气预测数据失败：" + e.getMessage());
        }
    }

    public CommonResponse<QWeatherCommonResponse> minutelyPrecipitation(String city) {
        try {
            QWeatherLocation location = searchCity(city);
            if (location == null) {
                return CommonResponse.failure("获取城市ID失败");
            }

            String url = String.format(qWeatherUrlConfig.getMinutelyPrecipitation(), apiHost,
                    location.getLon() + "," + location.getLat());
            HttpEntity<Void> entity = new HttpEntity<>(getHeaders());
            ResponseEntity<QWeatherCommonResponse> response = restTemplate.exchange(url, HttpMethod.GET, entity,
                    QWeatherCommonResponse.class);
            return CommonResponse.success(response.getBody());
        } catch (Exception e) {
            return CommonResponse.failure("获取雨水预测数据失败：" + e.getMessage());
        }
    }

    public CommonResponse<QWeatherCommonResponse> weatherWarning(String city) {
        try {
            QWeatherLocation location = searchCity(city);
            if (location == null) {
                return CommonResponse.failure("获取城市ID失败");
            }

            String url = String.format(qWeatherUrlConfig.getWeatherWarning(), apiHost,
                    location.getLon() + "," + location.getLat());
            HttpEntity<Void> entity = new HttpEntity<>(getHeaders());
            ResponseEntity<QWeatherCommonResponse> response = restTemplate.exchange(url, HttpMethod.GET, entity,
                    QWeatherCommonResponse.class);
            return CommonResponse.success(response.getBody());
        } catch (Exception e) {
            return CommonResponse.failure("获取恶劣天气预测数据失败：" + e.getMessage());
        }
    }

    public CommonResponse<QWeatherLocationResponse> lookupCity(String city) {
        String url = String.format(qWeatherUrlConfig.getCityLookup(), apiHost, city);
        try {
            HttpEntity<Void> entity = new HttpEntity<>(getHeaders());
            ResponseEntity<QWeatherLocationResponse> response = restTemplate.exchange(url, HttpMethod.GET, entity,
                    QWeatherLocationResponse.class);
            return CommonResponse.success(response.getBody());
        } catch (Exception e) {
            return CommonResponse.failure("查询城市失败：" + e.getMessage());
        }
    }

    /**
     * 通过城市名称查询城市信息
     *
     * @param city 城市名称，如芝罘区
     * @return QWeatherLocation
     * @see <a href="https://dev.qweather.com/docs/api/geoapi/city-lookup/">城市搜索</a>
     */
    public QWeatherLocation searchCity(String city) {
        String url = String.format(qWeatherUrlConfig.getCityLookup(), apiHost, city);
        try {
            HttpEntity<Void> entity = new HttpEntity<>(getHeaders());
            ResponseEntity<QWeatherLocationResponse> response = restTemplate.exchange(url, HttpMethod.GET, entity,
                    QWeatherLocationResponse.class);
            if (response.getBody() != null && response.getBody().getLocation() != null
                    && !response.getBody().getLocation().isEmpty()) {
                return response.getBody().getLocation().get(0);
            }
        } catch (Exception e) {
            return null;
        }
        return null;
    }

    public HttpHeaders getHeaders() {
        HttpHeaders headers = new HttpHeaders();
        String token = qWeatherJwtProvider.getToken();
        headers.set("Authorization", "Bearer " + token);
        headers.set("Content-Type", "application/json; charset=utf-8");
        headers.set("Accept", "application/json");
        headers.set("Connection", "keep-alive");
        headers.set("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36");
        headers.set("Accept-Language", "zh-CN,zh;q=0.9");
        headers.set("Accept-Encoding", "gzip, deflate, br");
        return headers;
    }

}
